/******************************************************************************
 * Copyright (C) 2015  671643387@qq.com
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 *****************************************************************************/

#ifndef SHARED_LOG_LOG_H_
#define SHARED_LOG_LOG_H_

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif

#include <cstdio>
#include "Shared/Global_Macros.h"
#include "Shared/Util/IniFile.h"

namespace Shared {
    
    ///////////////////////////////////////////////////////////////////////////
    enum LogLevel
    {
        LOG_LVL_MINIMAL = 0,
        LOG_LVL_BASIC   = 1,
        LOG_LVL_DETAIL  = 2,
        LOG_LVL_DEBUG   = 3
    };

    ///////////////////////////////////////////////////////////////////////////
    enum Color
    {
        BLACK,
        RED,
        GREEN,
        BROWN,
        BLUE,
        MAGENTA,
        CYAN,
        GREY,
        YELLOW,
        LRED,
        LGREEN,
        LBLUE,
        LMAGENTA,
        LCYAN,
        WHITE
    };
    const int COLOR_COUNT = int(WHITE) + 1;

    ///////////////////////////////////////////////////////////////////////////
    class Log
    {
    public:
        Log(void);
        ~Log(void);

        bool initialize(Util::IniFile *config);
        void setLogLevel(LogLevel level);

        void outString(void);
        void outString(const char* str, ...);
        void outError(const char* err, ...);
        void outBasic(const char* str, ...);
        void outDetail(const char* str, ...);
        void outDebug(const char* str, ...);

        void outDbError(const char* err, ...);

        static Log *instance(void);

    private:
        void initColors(const std::string& str);
        void setColor(bool stdoutStream, Color color);
        void resetColor(bool stdoutStream);
        void outTimestamp(FILE* file);
        void outTime(void);

        void uninitialize(void);


        LogLevel _logLevel;
        bool _includeTime;
        bool _colored;

        Color _colors[4];
        static Log *_instance;
        DISALLOW_COPY_AND_ASSIGN(Log);
    };

}

#define sharedLog  (*(Shared::Log::instance()))

#endif // SHARED_LOG_LOG_H_
